package br.com.healthapplet.applet;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Label;
import java.util.concurrent.LinkedBlockingQueue;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;

import br.com.healthapplet.util.Constants;
import br.com.healthapplet.util.ImageUtil;
import br.com.healthapplet.util.ServerUtil;

import com.digitalpersona.onetouch.DPFPDataPurpose;
import com.digitalpersona.onetouch.DPFPFeatureSet;
import com.digitalpersona.onetouch.DPFPFingerIndex;
import com.digitalpersona.onetouch.DPFPGlobal;
import com.digitalpersona.onetouch.DPFPSample;
import com.digitalpersona.onetouch.DPFPTemplate;
import com.digitalpersona.onetouch._impl.DPFPTemplateFactoryImpl;
import com.digitalpersona.onetouch.capture.DPFPCapture;
import com.digitalpersona.onetouch.capture.DPFPCapturePriority;
import com.digitalpersona.onetouch.capture.event.DPFPDataEvent;
import com.digitalpersona.onetouch.capture.event.DPFPDataListener;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusAdapter;
import com.digitalpersona.onetouch.capture.event.DPFPReaderStatusEvent;
import com.digitalpersona.onetouch.processing.DPFPFeatureExtraction;
import com.digitalpersona.onetouch.verification.DPFPVerification;
import com.digitalpersona.onetouch.verification.DPFPVerificationResult;

public class CompareApplet extends JApplet{

	/**
	 * 
	 */
	private static final long serialVersionUID = -5351742959693684697L;	
	
	private Label appletLabel;
	
	private LinkedBlockingQueue<DPFPSample> samples;
	
	private DPFPFingerIndex finger;
	
	private DPFPFeatureSet featureSet;
	
	private String consultaId;
	
	private JLabel picture = new JLabel();
	
	private JPanel center;
	
	private ImageUtil imageUtil;
	
	private ServerUtil serverUtil;
	
	private DPFPFeatureExtraction featureExtractor;
	
	public void init() {
		featureExtractor = DPFPGlobal
				.getFeatureExtractionFactory().createFeatureExtraction();
		
		appletLabel = new Label("Applet iniciado.",Label.CENTER);
		center = new JPanel(new BorderLayout());
		imageUtil = new ImageUtil();
		serverUtil = new ServerUtil();
		consultaId = getParameter("consultaId");
		finger = DPFPFingerIndex.RIGHT_INDEX;
		samples = new LinkedBlockingQueue<DPFPSample>();
		
		picture.setBorder(BorderFactory.createLoweredBevelBorder());
		picture.setPreferredSize(new Dimension(400,280));
		
		appletLabel.setText("Coloque o dedo indicador da mao direita no leitor.");
		
		center.setBackground(Color.GRAY);
		center.add(picture, BorderLayout.NORTH);
		center.add(appletLabel, BorderLayout.SOUTH);
		
		add(center);
	}
	
	public void start(){
		
		boolean verify = false;
		byte[] templateBytes;
		
		while(!verify){
			DPFPSample sample;
			try {
				sample = getSample();
					
				drawPicture(imageUtil.convertSampleToBitmap(sample));
						
				featureSet = featureExtractor.createFeatureSet(
							sample, DPFPDataPurpose.DATA_PURPOSE_VERIFICATION);
						
			} catch (Exception e) {
				e.getStackTrace();
				appletLabel.setText("Tente novamente.");
				stop();
			}
			
			DPFPTemplateFactoryImpl templateFactory = new DPFPTemplateFactoryImpl();
			
			try {
				templateBytes = serverUtil.callBiometriaTemplateGetter(finger.toString(), consultaId, Constants.URL_BIOMETRIA_TEMPLATE_GETTER);
				
				if(templateBytes != null) {
					
					DPFPTemplate template = templateFactory.createTemplate(templateBytes);
					
					DPFPVerification matcher = DPFPGlobal.getVerificationFactory().createVerification();
					
					matcher.setFARRequested(DPFPVerification.MEDIUM_SECURITY_FAR);
							
					DPFPVerificationResult result = matcher.verify(featureSet, template);
					
					if (result.isVerified()) {
						verify = true;
					}
				}
				
				if(verify){
					serverUtil.callConfirmBiometriaCompareServer(consultaId, Constants.URL_CONFIRM_COMPARER);
					appletLabel.setText("Sucesso, favor iniciar a consulta.");
				} else {
					appletLabel.setText("Biometria inválida.");
				}
			}catch (Exception e) {
				e.getStackTrace();
				appletLabel.setText("Erro.");
				stop();
			}
		}
	}
	
	public void stop(){
		destroy();
		init();
	}
	
	private void drawPicture(Image image) {
		picture.setIcon(new ImageIcon(
			image.getScaledInstance(picture.getWidth(), picture.getHeight(), Image.SCALE_DEFAULT)));
	}
	
	private DPFPSample getSample() throws Exception {
		
		DPFPCapture capture = DPFPGlobal.getCaptureFactory().createCapture();
		
		capture.setPriority(DPFPCapturePriority.CAPTURE_PRIORITY_LOW);
		
		capture.addDataListener(new DPFPDataListener() {
			public void dataAcquired(DPFPDataEvent e) {
				if (e != null && e.getSample() != null) {
					try {
						samples.put(e.getSample());
					} catch (Exception e1) {
						e1.printStackTrace();
						stop();
					}
				}
			}
		});
		
		capture.addReaderStatusListener(new DPFPReaderStatusAdapter() {
			int lastStatus = DPFPReaderStatusEvent.READER_CONNECTED;

			public void readerConnected(DPFPReaderStatusEvent e) {
				if (lastStatus != e.getReaderStatus())
					appletLabel.setText("Leitor conectado.");
				lastStatus = e.getReaderStatus();
			}

			public void readerDisconnected(DPFPReaderStatusEvent e) {
				if (lastStatus != e.getReaderStatus()){
					appletLabel.setText("O leitor esta desconectado.");
				}
				lastStatus = e.getReaderStatus();
			}

		});
		
		try {
			capture.startCapture();
			return samples.take();
		} catch (Exception e) {
			appletLabel.setText("Falha ao verificar a biometria.");
			stop();
			e.getStackTrace();
			return null;
		} finally {
			capture.stopCapture();
		}
	}
}
